<template>
	<div ref="chartRef" v-loading="resizeLoading" class="chart"></div>
</template>
<script lang="ts" setup>
import dayjs from 'dayjs';
import * as echarts from 'echarts';
import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue';
import { LineChartData } from '/@/types';
// import { message } from '/@/utils/message';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useCharts } from '/@/stores/charts';
import { storeToRefs } from 'pinia';

const { proxy } = <any>getCurrentInstance();
const props = withDefaults(
	defineProps<{
		name: string|null,
		// type
		type:string;
		// data
		data:LineChartData;
		// title
		title: string;
		// x title
		xTitle: string;
		// y title
		yTitle: string;
		// x unit
		xUnit:string;
		// y unit
		yUnit:string;
		xIntervalShow:number
		turnOnInsideDataZoom:boolean;
	}>(),
	{
		name: null,
		type: 'time',
		title: '',
		xTitle: '',
		yTitle: '',
		xUnit: '',
		yUnit: '',
		xIntervalShow: 1,
		turnOnInsideDataZoom: false
	}
);
const chartRef = ref<HTMLDivElement>();
const myChart = shallowRef();
const option = computed(() => ({
	title: {
		text: props.title
	},
	tooltip: {
		trigger: 'axis',
		confine: true,
		extraCssText: 'white-space: normal; word-break: break-all;',
		formatter: (params:any) => {
			let str = `<div><p>${dayjs(params[0].value[0]).format('YYYY-MM-DD HH:mm:ss')}</p>`;
			for (let item of params) {
				let value = null;
				let yUnit = props.yUnit;
				if (typeof (item.data[1]) === 'number') {
					value = item.data[1].toFixed(3);

					// units toggle
					if (props.yUnit === 'KB') {
						if (value >= 1024 * 1024) {
							value = (value / 1024 / 1024).toFixed(2);
							yUnit = 'GB';
						} else if (value >= 1024) {
							value = (value / 1024).toFixed(2);
							yUnit = 'MB';
						}
					}
					if (props.yUnit === 'MB') {
						if (value >= 1024) {
							value = (value / 1024).toFixed(2);
							yUnit = 'GB';
						}
					}
					if (props.yUnit === 'B/s' || props.yUnit === 'kBs') {
						if (value >= 1024 * 1024 * 1024) {
							value = (value / 1024 / 1024 / 1024).toFixed(2);
							yUnit = 'GB/s';
						} else if (value >= 1024 * 1024) {
							value = (value / 1024 / 1024).toFixed(2);
							yUnit = 'MB/s';
						} else if (value >= 1024) {
							value = (value / 1024).toFixed(2);
							yUnit = 'KB/s';
						}
					}
					if (props.yUnit === 'B') {
						if (value >= 1024 * 1024 * 1024) {
							value = (value / 1024 / 1024 / 1024).toFixed(2);
							yUnit = 'GB';
						} else if (value >= 1024 * 1024) {
							value = (value / 1024 / 1024).toFixed(2);
							yUnit = 'MB';
						} else if
						(value >= 1024) {
							value = (value / 1024).toFixed(2);
							yUnit = 'KB';
						}
					}
					if (props.yUnit === 'ns') {
						if (value >= 1000 * 1000 * 1000) {
							value = (value / 1000 / 1000 / 1000).toFixed(2);
							yUnit = 's';
						} else if 	(value >= 1000 * 1000) {
							value = (value / 1000 / 1000).toFixed(2);
							yUnit = 'ms';
						} else if 	(value >= 1000) {
							value = (value / 1000 / 1000).toFixed(2);
							yUnit = 'us';
						}
					}
					if (props.yUnit === 's') {
						if (value < 0.001 * 0.001 * 0.1) {
							value = (value * 1000 * 1000 * 1000).toFixed(2);
							yUnit = 'ns';
						} else if (value < 0.001 * 0.1) {
							value = (value * 1000 * 1000).toFixed(2);
							yUnit = 'us';
						} else if (value < 1) {
							value = (value * 1000).toFixed(2);
							yUnit = 'ms';
						}
					}

					str += `<p style="display:flex;justify-content:space-between;align-items:center;">
							<span>
								<span style="display:inline-block;width:10px;height:10px;border-radius:10px;background:${item.color};margin-right:5px;"></span>
								<span>${item.seriesName}</span>
							</span>
							<span style="font-weight:bold;">${value} ${yUnit}</span>
						</p>`;
				} else {
					str += `<p style="display:flex;justify-content:space-between;align-items:center;">
							<span>
								<span style="display:inline-block;width:10px;height:10px;border-radius:10px;background:${item.color};margin-right:5px;"></span>
								<span>${item.seriesName}</span>
							</span>
							<span style="font-weight:bold;">暂无数据</span>
						</p>`;
				}
			}
			str += '</div>';
			return str;
		}
	},
	legend: {
		width: '80%',
		right: 0,
		type: 'scroll',
		data: props.data.seriesNames,
		selected: props.name && getLegendSelected.value[activeTab.value][props.name]
	},
	dataZoom: {
		type: 'inside',
		filterMode: 'none',
		disabled: !props.turnOnInsideDataZoom
	},
	toolbox: {
		feature: {
			dataZoom: {
				yAxisIndex: 'none',
				icon: {
					zoom: 'none',
					back: 'none'
				}
			},
		}
	},
	grid: {
		left: 10,
		right: 15,
		bottom: 0,
		containLabel: true
	},
	xAxis: {
		type: props.type,
		name: props.xTitle,
		min: null as any,
		max: null as any,
		boundaryGap: false,
		data: props.type === 'category' && props.data.xNames,
		axisLabel: {
			formatter: function(value:any, index:any) {
				let remainder = index % props.xIntervalShow;
				if (remainder === 0) {
					return `{dd}日{HH}:{mm}${props.xUnit}`;
				} else {
					return '';
				}
			}
		}
	},
	yAxis: {
		type: 'value',
		name: props.yTitle,
		min: null as any,
		max: null as any,
		axisLabel: {
			// formatter: `{value} ${props.yUnit}`
			formatter: function(value:any) {
				// units toggle
				let yUnit = props.yUnit;
				if (props.yUnit === 'KB') {
					if (value >= 1024 * 1024) {
						value = (value / 1024 / 1024).toFixed(2);
						yUnit = 'GB';
					} else if (value >= 1024) {
						value = (value / 1024).toFixed(2);
						yUnit = 'MB';
					}
				}
				if (props.yUnit === 'MB') {
					if (value >= 1024) {
						value = (value / 1024).toFixed(2);
						yUnit = 'GB';
					}
				}
				if (props.yUnit === 'B/s' || props.yUnit === 'kBs') {
					if (value >= 1024 * 1024 * 1024) {
						value = (value / 1024 / 1024 / 1024).toFixed(2);
						yUnit = 'GB/s';
					} else if (value >= 1024 * 1024) {
						value = (value / 1024 / 1024).toFixed(2);
						yUnit = 'MB/s';
					} else if (value >= 1024) {
						value = (value / 1024).toFixed(2);
						yUnit = 'KB/s';
					}
				}
				if (props.yUnit === 'B') {
					if (value >= 1024 * 1024 * 1024) {
						value = (value / 1024 / 1024 / 1024).toFixed(2);
						yUnit = 'GB';
					} else if (value >= 1024 * 1024) {
						value = (value / 1024 / 1024).toFixed(2);
						yUnit = 'MB';
					} else if
					(value >= 1024) {
						value = (value / 1024).toFixed(2);
						yUnit = 'KB';
					}
				}
				if (props.yUnit === 'ns') {
					if (value >= 1000 * 1000 * 1000) {
						value = (value / 1000 / 1000 / 1000).toFixed(2);
						yUnit = 's';
					} else if 	(value >= 1000 * 1000) {
						value = (value / 1000 / 1000).toFixed(2);
						yUnit = 'ms';
					} else if 	(value >= 1000) {
						value = (value / 1000 / 1000).toFixed(2);
						yUnit = 'us';
					}
				}
				if (props.yUnit === 's') {
					if (value < 0.001 * 0.001 * 0.1) {
						value = (value * 1000 * 1000 * 1000).toFixed(2);
						yUnit = 'ns';
					} else if (value < 0.001 * 0.1) {
						value = (value * 1000 * 1000).toFixed(2);
						yUnit = 'us';
					} else if (value < 1) {
						value = (value * 1000).toFixed(2);
						yUnit = 'ms';
					}
				}

				return value + yUnit;
			}
		}
	},
	series: props.data.seriesData
}));

// Draw chart
const drawChart = () => {
	if (chartRef.value) {
		if (!myChart.value) {
			myChart.value = echarts.init(chartRef.value);
			// myChart.value.showLoading({
			// 	text: '图表加载中...',
			// 	fontSize: '16px',
			// 	maskColor: '#ffffff',
			// });
			myChart.value.on('datazoom', (event:any) => {
				const startTime = dayjs(event.batch[0].startValue).format('YYYY-MM-DD HH:mm:ss');
				const endTime = dayjs(event.batch[0].endValue).format('YYYY-MM-DD HH:mm:ss');
				proxy.mittBus.emit('change-range-time', [startTime, endTime]);
			});
		}

		if (props.data.seriesData.length === 0) {
			// myChart.value.showLoading({
			// 	text: '暂无数据',
			// 	showSpinner: false,
			// 	textColor: '#ccc',
			// 	maskColor: 'rgba(255, 255, 255, 1)',
			// 	fontSize: '16px',
			// 	fontWeight: 'bold'
			// });
			option.value.xAxis.min = 0;
			option.value.xAxis.max = new Date().getTime();
			option.value.yAxis.min = 0;
			option.value.yAxis.max = 100;
		}
		myChart.value.setOption(option.value, true);
	}
};
// Reset Chart Container
const resize = () => {
	myChart.value.resize({
		animation: {
			duration: 200,
			easing: 'linear'
		}
	});
};
const datetimerange = inject('datetimerange', ref());
// Data change and redraw the chart
watch(
	() => props.data,
	() => {
		drawChart();

		// myChart.value.hideLoading();
		// Turn off zoom if the time interval differs by one minute

		let open = true;

		if (datetimerange.value && dayjs(datetimerange.value[1]).diff(datetimerange.value[0], 'minute') < 1) {
			open = false;
			// message.warning('图表显示区域小于1分钟，关闭缩放功能');
		}
		myChart.value.dispatchAction({
			type: 'takeGlobalCursor',
			key: 'dataZoomSelect',
			dataZoomSelectActive: open
		});
	}
);

const storesThemeConfig = useThemeConfig();
const activeTab = inject('activeTab', ref('cluster'));
const { themeConfig } = storeToRefs(storesThemeConfig);
watch(
	() => themeConfig.value.isCollapse,
	() => {
		setTimeout(() => {
			resize();
		}, 600);
	}
);

const resizeLoading = ref(false);
watch(
	() => activeTab.value,
	() => {
		resizeLoading.value = true;
		setTimeout(() => {
			resize();
			resizeLoading.value = false;
		}, 500);
	}
);

const storesCharts = useCharts();
const { legendSelected } = storeToRefs(storesCharts);
const getLegendSelected = computed(() => {
	return legendSelected.value;
});
onMounted(() => {
	drawChart();
	window.addEventListener('resize', resize);
	// save legendselected when the change charts legendselected
	myChart?.value.on('legendselectchanged', function(params:any) {
		props.name && storesCharts.setLegendStatus(props.name, activeTab.value, params.selected);
	});
});
onUnmounted(() => {
	window.removeEventListener('resize', resize);
});
</script>
<style lang="scss" scoped>
.chart{
    width: 100%;
    height: 100%;
}
</style>